#include "reflection.h"
#include "scene.h"
#include "textures.h"

using namespace Scene;
using namespace Textures;

namespace Reflection
{

void reflection_mapping()
{
	vector4 v[4];
	v[0] = vector4(1,0,0,0);
	v[1] = vector4(0,1,0,0);
	v[2] = vector4(0,0,1,0);
	v[3] = vector4(0,0,0,1);		
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_S, GL_EYE_PLANE, (float*)&(v[0]));
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_T, GL_EYE_PLANE, (float*)&(v[1]));
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_R, GL_EYE_PLANE, (float*)&(v[2]));
	glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGenfv(GL_Q, GL_EYE_PLANE, (float*)&(v[3]));
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);
	glEnable(GL_TEXTURE_GEN_Q);
	glPopMatrix();
	glMatrixMode(GL_TEXTURE);
	matrix44 mProj = TranslateMatrix44(0.5, 0.5, 0.5) * ScaleMatrix44(0.5, 0.5, 0.5, 1.0) * matProj;
	glLoadMatrixf((float*)&(mProj));
	glMatrixMode(GL_MODELVIEW);
}

void render_reflection(void (*render_scene)())
{
	double cp[4] = {.0f,.0f,-1.0f,table_h+table_pos.z-0.001f};
	if (camera_pos.z < cp[3])
	{
		cp[3] = -cp[3];
		cp[2] = -cp[2];
	}
	glEnable(GL_CLIP_PLANE0);
	glClipPlane(GL_CLIP_PLANE0, cp);

	glPushMatrix();
	glTranslatef(.0f,.0f,table_h+table_pos.z);
	glScalef(1.0f,1.0f,-1.0f);
	glTranslatef(.0f,.0f,-(table_h+table_pos.z));

	matrix44 matViewBak = matView;
	matrix44 matReflect = TranslateMatrix44(.0f,.0f,table_h+table_pos.z) * ScaleMatrix44(1.0f,1.0f,-1.0f) * TranslateMatrix44(.0f,.0f,-(table_h+table_pos.z));
	matView = matView * matReflect;
	vector4 camera_posBak = camera_pos;
	camera_pos = matReflect * camera_pos;
	Scene::mirror = true;

	glFrontFace(GL_CW);
	render_scene();
	glFrontFace(GL_CCW);

	glPopMatrix();

	Scene::mirror = false;
	matView = matViewBak;
	camera_pos = camera_posBak;

	glDisable(GL_CLIP_PLANE0);

	glBindTexture(GL_TEXTURE_2D, tex_reflect);
	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, w, h, 0); 
}

}